import { App } from "../../../../src/App";
import { Singleton } from "../../../../src/core/Class";

// 日历格式
const CALENDARNAMES = ['yyyy年', 'yyyy年mm月', 'yyyy年mm月dd日'];

// 日期类型
enum DAYTYPE {
	TODAY = 0,
	YESTERDAY = 1,
	TOMORROW = 2,
	NONE = 3,
}

// 日历类型 日、月、年、周
enum CALENDAR {
	YEAR = 0,
	MONTH = 1,
	DAY = 2,
	WEEK = 3, // 周 暂未使用
}
class CData extends Singleton<CData> {

	// 实时日期
	public nowDate: Date;
	// 显示日期
	public selDate: Date;
	// 日历类型
	public cutType: CALENDAR;

	public constructor() {
        super();
		this.cutType = CALENDAR.YEAR;
		let now = new Date();
		let year = now.getFullYear();
		let month = now.getMonth();
		let day = now.getDate();
		this.nowDate = new Date(year, month, day);
		this.selDate = new Date(year, month, day);
	}

	/**
	 * 当前日期与实时日期是否在同年同月
	 * @param day
	 * @returns
	 */
	public isNowMonth(month: number) {
		return (this.nowDate.getFullYear() === this.selDate.getFullYear() && this.nowDate.getMonth() === month);
	}

	/**
	 * 当前日期与实时日期是否在同年同月同日
	 * @param day
	 * @returns
	 */
	public isNowDay(day: number) {
		return (this.nowDate.getFullYear() === this.selDate.getFullYear() && 
            this.nowDate.getMonth() === this.selDate.getMonth() && 
            this.nowDate.getDate() === day);
	}

	/**
	 * 是否与选择日期在同年同月同日
	 * @param year
	 * @param month
	 * @param day
	 * @returns
	 */
	public isSel(year: number, month: number, day: number) {
		return (this.selDate.getFullYear() === year && this.selDate.getMonth() === month && this.selDate.getDate() === day);
	}
}
const Data:CData = CData.getInstance<CData>(CData);

const {ccclass, property} = cc._decorator;
const EnMonth = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
@ccclass
export default class Calendar extends cc.Component {
	@property({ type: cc.Node, tooltip: '内容' })
	content: cc.Node = null;

	@property({ type: cc.Node, tooltip: '天Item' })
	dayNode: cc.Node = null;

	@property({ type: cc.Label, tooltip: '月份' })
	lblMonth: cc.Label = null;

	@property({ tooltip: '是否显示日期背景' })
	isShowDayBg: boolean = true;

	private _list: cc.Node[] = [];
    private _curMonth:number = 0;
    private _itemPool:cc.NodePool = null;

    onLoad(){
		this.dayNode.active = false;
        this._curMonth = (new Date()).getMonth()+1;
        while(this._list.length < 42)this._list.push(cc.instantiate(this.dayNode));
        this._itemPool = new cc.NodePool('cc.Node');
    }

    onDestroy(){
		this._list.forEach((it)=>{
			
		});
		while (this._itemPool.size() > 0){
			const it = this._itemPool.get();
			it.off(cc.Node.EventType.TOUCH_START);
			it.off(cc.Node.EventType.TOUCH_MOVE);
			it.off(cc.Node.EventType.TOUCH_END);
			it.off(cc.Node.EventType.TOUCH_CANCEL);
		} 
		this._itemPool.clear();
    }

	public init(){
        const CurDate = new Date();
		this._createLast(CurDate.getFullYear(),CurDate.getMonth(),false);
		this._createNow(CurDate.getFullYear(),CurDate.getMonth());
		this._createNext(CurDate.getFullYear(),CurDate.getMonth(),false);
	}

	private _setText(item:cc.Node, day: number) {
        item && App.setLableText(item,'lblText',`${day}`);
	}

	// 显示背景
	private _setBg(item:cc.Node, isShow:boolean=true,col:cc.Color = cc.Color.WHITE) {
        const bgNode = item ? item.getChildByName('bgImg'): null;
        if (App.Util.isValid(bgNode)){
            bgNode.active = isShow;
            isShow && (bgNode.color = col);
        }
	}

    private _showHide(item:cc.Node,isShow:boolean=true,col:cc.Color = cc.Color.BLACK){
        if (App.Util.isInvalid(item)) return ;
        item.active = isShow;
        isShow && (item.color = col);
    }

    private get _newItem():cc.Node {
        return this._itemPool.get() || cc.instantiate(this.dayNode);
    }

    private _createNext(year: number, month: number, isTouch: boolean = true, opacity: number = 100) {
		this.lblMonth.string = EnMonth[month];
		// 下月初
		const nextMonthStart = new Date(year, month + 1, 1);
		// 下月初周几
		let nextMonthWeek = nextMonthStart.getDay();
		if (nextMonthWeek > 0) {
			for (let idx = 1; idx < 8 - nextMonthWeek; idx++) {
				let it = this._newItem;
                this._setText(it,idx);
                this._setBg(it,this.isShowDayBg);
                this._showHide(it);
				it.parent = this.content;
				it.opacity = opacity;
				this._list.push(it);
				it.scale = 1;

				if (isTouch) {
                    it.on(cc.Node.EventType.TOUCH_START,()=>{
                        for (const day of this._list) this._setBg(day,this.isShowDayBg);
                        this._setBg(it,this.isShowDayBg,cc.Color.YELLOW);
                    },this);
					it.on(cc.Node.EventType.TOUCH_END, ()=>{
                        Data.selDate = new Date(year, month + 1, idx);
                    }, this);
				}
			}
		}
	}
	/**
	 * 创建上月
	 */
     private _createLast(year: number, month: number, isTouch: boolean = true, opacity: number = 100) {
		this.lblMonth.string = EnMonth[month];
		// 上月末
		let lastMonthEnd = new Date(year, month, 0);
		// 上月日数
		let lastMonthDay = lastMonthEnd.getDate();
		// 上月末周几
		let lastMontWeek = lastMonthEnd.getDay();
		if (lastMontWeek < 6) {
			for (let idx = lastMontWeek; idx > -1; idx--) {
				let it = this._newItem;
                this._setText(it,lastMonthDay-idx);
                this._setBg(it,this.isShowDayBg);
                this._showHide(it);
				it.parent = this.content;
				it.opacity = opacity;
				this._list.push(it);
				it.scale = 1;

				if (isTouch) {
					it.on(cc.Node.EventType.TOUCH_START, ()=>{
                        for (const day of this._list) this._setBg(day,this.isShowDayBg);
                        this._setBg(it,this.isShowDayBg,cc.Color.YELLOW);
                    },this,);

					it.on(cc.Node.EventType.TOUCH_END, ()=>{
                        Data.selDate = new Date(year, month - 1, lastMonthDay - idx);
                    },this);
				}
			}
		}
	}

	/**
	 * 创建本月
	 */
     private _createNow(year: number, month: number, isTouch: boolean = true, opacity: number = 255) {
		this.lblMonth.string = EnMonth[month];
		let lastMonthEnd = new Date(year, month + 1, 0);// 本月末
		let nowMonthDay = lastMonthEnd.getDate();// 本月日数
		let isNowMonth = Data.isNowMonth(month);// 本月标志
		let toDay:number = 1;
		for (let idx = 1; idx < nowMonthDay + 1; idx++) {
            let it = this._newItem;
            this._setText(it,idx);
            this._setBg(it,this.isShowDayBg);
            this._showHide(it);
            it.parent = this.content;
            it.opacity = opacity;
			it['idx'] = idx;
            this._list.push(it);
            it.scale = 1;

			let _touch = isTouch;
			if (isNowMonth && Data.isNowDay(idx)){
				toDay = idx;
				this._setBg(it,true,cc.color(49,146,113));
				it.getChildByName('bgImg').opacity = 160;
				_touch = false;
			}

			_touch && it.on(cc.Node.EventType.TOUCH_END, ()=>{
				for (const day of this._list){
					day['idx'] !== toDay && this._setBg(day,this.isShowDayBg);
				} 
				if (it['idx'] !== toDay){
					this._setBg(it,true,cc.Color.YELLOW);
					setTimeout(() => {
						this._setBg(it,this.isShowDayBg,cc.Color.WHITE);
					}, 2000);
				}
				Data.selDate = new Date(year, month, idx);
			},this,
		);
		}
	}
}
